from info import constants, db
from info.models import News, User, Comment
from info.utils.response_code import RET
from . import news_blue
from flask import render_template, current_app, session, jsonify, g, abort, request
from info.utils.common import user_login_data


# 新闻评论接口
@news_blue.route('/news_comment', methods=["POST"])
@user_login_data
def add_news_comment():
    """添加评论"""

    # 1 获取参数 判断用户是否登录
    user = g.user
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")
    # 获取参数
    data_dict = request.json
    news_id = data_dict.get("news_id")
    comment_str = data_dict.get("comment")
    parent_id = data_dict.get("parent_id")

    # 2 校验参数
    if not all([news_id, comment_str]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")

    # 查询数据库
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询数据失败")

    if not news:
        return jsonify(errno=RET.NODATA, errmsg="该新闻不存在")

    # 3 创建评论模型--> 添加到数据库中 返回给前端页面
    # 用户id 新闻id 评论内容
    comment = Comment()
    comment.user_id = user.id
    comment.news_id = news.id
    comment.content = comment_str

    if parent_id:
        # 如果有父id
        comment.parent_id = parent_id

    # 提交数据库之后 才会有该模型的id 前端需要
    try:
        db.session.add(comment)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询失败')

    return jsonify(errno=RET.OK, errmsg='成功', data=comment.to_dict())


# 实现收藏点击的接口
@news_blue.route("/news_collect", methods=['POST'])
@user_login_data
def news_collect():
    """新闻收藏"""

    # 1 获取参数 如果需要登陆 还需要获取用户信息
    user = g.user
    json_data = request.json
    news_id = json_data.get("news_id")
    action = json_data.get("action")

    # 2 校验参数
    if not user:
        return jsonify(errno=RET.SESSIONERR, errmsg="用户未登录")

    if not all([news_id, action]):
        return jsonify(errno=RET.PARAMERR, errmsg="参数不全")

    if action not in ("collect", "cancel_collect"):
        return jsonify(errno=RET.PARAMERR, errmsg="参数错误")

    # 3 逻辑处理 根据不同的需求进行处理(收藏/取消)
    # 3.1 查询新闻
    try:
        news = News.query.get(news_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询失败')
    if not news:
        return jsonify(errno=RET.NODATA, errmsg='数据不存在')

    if action == 'collect':
        if news not in user.collection_news:
            user.collection_news.append(news)
    else:
        if news in user.collection_news:
            user.collection_news.remove(news)

    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询失败')
    # 返回数据
    return jsonify(errno=RET.OK, errmsg='成功')


# 新闻详情页的接口
@news_blue.route('/<int:news_id>')
@user_login_data
def get_news(news_id):

    # 登录
    # 我们可以在登陆的时候返回session信息 如果有的话
    # 1 从session中获取用户id
    # user_id = session.get('user_id', None)
    # user = None
    # # 2 如果user_id 存在 就查询数据库
    # if user_id:
    #     try:
    #         user = User.query.get(user_id)
    #     except Exception as e:
    #         current_app.logger.error(e)
    #         return jsonify(errno=RET.DBERR, errmsg='查询失败')
    user = g.user
    # 二 分类排行
    news_list = []
    try:
        # 有序 降序 查询 点击  显示多少条
        news_list = News.query.order_by(News.clicks.desc()).limit(constants.CLICK_RANK_MAX_NEWS)
    except Exception as e:
        current_app.logger.error(e)
        # return jsonify(errno=RET.DBERR, ermasg='查询数据库失败')
    news_dict_li = []
    for news in news_list:
        news_dict_li.append(news.to_basic_dict())

    # 三 查询新闻数据
    try:
        news = News.query.get(news_id)
    except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=RET.DBERR, errmsg='查询失败')
    if not news:
        abort(404)

    news.clicks += 1

    try:

        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='提交失败')

    # 四 收藏信息
    is_collected = False
    # 如果用户已登录 查询是否已收藏数据，如果有将属性改为True
    if user:
        if news in user.collection_news:
            is_collected = True

    # 五 获取评论数据
    # 查询数据库
    try:
        # 实际开发中可能用limit查询来限制加载评论的数量
        comment_model_list = Comment.query.filter(Comment.news_id == news_id).order_by(Comment.create_time.desc()).all()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg='查询失败')
    if not comment_model_list:
        return jsonify(errno=RET.NODATA, errmsg='数据不存在')
    comment_dict_list = []

    for comment in comment_model_list:
        comment_dict_list.append(comment.to_dict())


    data = {
        'user': user.to_dict() if user else None,
        'news_dict_li': news_dict_li,
        'news': news.to_dict(),
        'is_collected': is_collected,
        'comments': comment_dict_list
    }
    return render_template('news/detail.html', data=data)
